在上一篇文章中,我們介紹了 Web Notification API 的基本用法。然而在實際應用中,僅僅依靠前端觸發通知是遠遠不夠的。為了建立一個功能完整、實用的通知系統,我們需要將前端與後端技術結合起來。
在透過後端 Server 發送通知之前,我們需要先了解 Service Workers。Service Workers 允許網頁在後台運行腳本,即使在使用者關閉網站的情況下,依然能夠接收和處理通知。我會跟大家介紹如何使用 Service Workers 來接收和顯示通知,包括註冊 Service Workers、在 Service Workers 中處理通知、透過開發者工具觸發通知,以及使用 Web Push 測試工具來模擬通知的接收過程。
Service Workers 可以讓使用者在關閉網站的情況下,依然讓該網站在後台執行腳本。
Service Workers 為網頁應用提供了強大的發送通知功能,讓使用者在未打開頁面的情況下接收通知。但我們會先使用開發者工具體驗 Service Workers,所以還是要把網頁打開才能使用唷。
首先要註冊 Server Workers,第 2 行註冊的 sw.js
是處理通知的檔案,必須放在網站的根目錄
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js')
.then(registration => {
console.log('Service Worker 註冊成功:', registration);
})
.catch(error => {
console.error('Service Worker 註冊失敗:', error);
});
}
新增檔案 sw.js
,就是我們在註冊 Server Workers 時寫的那個檔案名稱,記得要放在網站的根目錄!重要~重要~重要
我監聽了四個事件:
install
和 active
透過 console.log()
的除錯訊息可以清楚知道事件的用途。push
:發送通知,等等會透過開發者工具的 Server Workers 來進行模擬。notificationclick
:點擊通知後要做的事情,上一篇文章的範例是點擊後會跳到一個網站,這裡也相同。self.addEventListener('install', event => {
console.log('Service Worker 安裝中...');
self.skipWaiting();
});
self.addEventListener('activate', event => {
console.log('Service Worker 已啟用');
});
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.body,
data: data.data
});
});
self.addEventListener('notificationclick', event => {
event.notification.close();
const url = event.notification.data.url;
event.waitUntil(
clients.openWindow(url)
);
});
開發者工具面板選擇「Application」-> 「Service workers」可以看到我們已經安裝的服務
其中一個欄位 Push 就是用來發送通知的事件。也就是我們在 sw.js 寫的這段程式碼
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.body,
data: data.data
});
});
透過第二行 event.data.json()
得知我們要傳送的是一個 JSON,會傳送 data.title
, data.body
, 以及 data.data
,所以 JSON 格式如下
{
"title": "這是通知標題",
"body": "這是通知內容",
"data": {
"url": "https://muki.tw/ngrok-err-ngrok-6024/"
}
}
把 JSON 貼到 push 的輸入框後再按下「Push」按鈕,就能收到通知了
要在網站關閉的情況下測試發送通知,我們需要發送通知的服務來發送通知,通常需要用後端 Server 來做這件事,但我們先用一些現有的服務來做測試吧!
有一些線上的 Web Push 測試工具可以幫助我們測試發送通知,今天要分享的是 Push Companion 網站的服務。
使用通知服務時,必須要有一組 public & private key,Push Companion 網站有直接提供我們測試的 key,所以暫時不需要申請。
這是我從 Push Companion 產生的 key:
Public Key
BDNzLXQEsMHUaZXjjyHzfi6HjLSg_6Vn1qskL3OYd-mAT6o_5Lggw4JSsNPkRKfA8Qbke2fHAgZMaALeTvShviY
Private Key
H2XUBO82HgMBrz93kNut5os7BTdTZWziY8qcAhKwgBQ
先來修改一下我們之前的程式碼,在 navigator.serviceWorker.register('sw.js')
後再呼叫 navigator.serviceWorker.ready
,完整程式碼如下:
// 在 Push Companion 網站產生的 publickey
const publicKey = 'BDNzLXQEsMHUaZXjjyHzfi6HjLSg_6Vn1qskL3OYd-mAT6o_5Lggw4JSsNPkRKfA8Qbke2fHAgZMaALeTvShviY';
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('sw.js')
.then(registration => {
console.log('Service Worker 註冊成功:', registration);
})
.catch(error => {
console.error('Service Worker 註冊失敗:', error);
});
// 新增 ready()
navigator.serviceWorker.ready.then(registration => {
return registration.pushManager.subscribe({
userVisibleOnly: true,
// 新增 urlBase64ToUint8Array() 解析publickey
applicationServerKey: urlBase64ToUint8Array(publicKey)
});
}).then(subscription => {
console.log('推送訂閱資訊:', JSON.stringify(subscription));
}).catch(error => {
console.error('推送訂閱失敗:', error);
});
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
回到網站打開 console 面板,可以看到印出的所有資訊。特別注意紅框處的地方,這是當發送訂閱成功時,會回傳的訂閱資訊,我們要將這段 JSON 複製起來,貼回 Push Companion 網站來發送通知。
複製好訂閱資訊,就可以關閉網站囉!因為我們要測試當網站關閉時,是否能順利收到通知。
在 Push Companion 網站上的 Subscription to Send To 欄位,貼上剛剛複製的訂閱資訊。在 Text to Send 欄位貼上我們要傳送的 JSON,就跟剛剛用開發者工具測試時的內容相同:
{
"title": "這是通知標題",
"body": "這是通知內容",
"data": {
"url": "https://muki.tw/ngrok-err-ngrok-6024/"
}
}
最後再按下「Send Push Message」按鈕,就可以看到通知囉!
通過註冊 Service Workers,我們能夠在後台運行腳本,進而在網站關閉的情況下接收通知。希望這篇文章能幫助各位更好地理解與使用 Service Workers 來實作通知功能,有任何問題或想要討論的部分,都歡迎留言告訴我唷。